# 作者： 迷路的小怪兽
# 创建时间： 2021/10/30 16:47
import demjson
import openpyxl
import json
from configparser import ConfigParser
import yaml
import pymysql
from xml.dom import minidom


class OptExcel:

    def __init__(self, file_name, read=True):
        """
        操作excel的基本操作类，可以根据需要扩展
        :param file_name: 文件路径（包含文件名）
        :param read: 是否读取模式
        """
        self.path = file_name
        if read is True:
            self.wk = openpyxl.load_workbook(file_name, data_only=True, read_only=True)
        else:
            self.wk = openpyxl.load_workbook(file_name)
        # 默认第一个页签为当前表
        self.sheet = self.wk[self.wk.sheetnames[0]]

    def set_current_sheet(self, name):
        self.sheet = self.wk[name]

    def get_cell_value(self, row, col):
        return self.sheet.cell(row, col).value

    def set_cell_value(self, row, col, value):
        """
        设置单元格的值，同时支持excel公式，形似‘=SUM(A1:A10)’
        :param row: 行
        :param col: 列
        :param value: 值或者表达式
        :return:
        """
        self.sheet.cell(row, col).value = value

    def get_row_data(self, row):
        row_data = []
        col_num = self.sheet.max_column
        for col in range(1, col_num + 1):
            row_data.append(self.get_cell_value(row, col))

        return row_data

    def set_row_data(self, row, data_list):
        col_num = self.sheet.max_column
        for col in range(1, col_num + 1):
            self.set_cell_value(row, col, data_list[col - 1])

    def get_column_data(self, column):
        col_data = []
        row_num = self.sheet.max_row
        for row in range(1, row_num + 1):
            col_data.append(self.get_cell_value(row, column))

        return col_data

    def set_column_data(self, column, data_list):
        row_num = self.sheet.max_row
        for row in range(1, row_num + 1):
            self.set_cell_value(row, column, data_list[row - 1])

    def save(self, filename=None):
        if filename is not None:
            _name = filename
        else:
            _name = self.path
        self.wk.save(_name)


class OptTXT:
    pass


class OptYaml:

    def __init__(self, file_path):
        self.file_path = file_path
        with open(self.file_path, 'r', encoding='utf-8') as fp:
            self._data = yaml.safe_load(fp)

    def get_data(self):
        return self._data

    # 获取的数据是字典格式，可以直接使用相关方法修改数据，不需要专门写修改数据的方法
    # def _set(self, key, value):
    #     key_seq = key.split('__')
    #     con_str = 'self._data'
    #     for key in key_seq:
    #         con_str += f'["{key}"]'
    #     con_str += f' = "{value}"'
    #     exec(con_str)
    #
    # def set_value(self, **kw):
    #     for key, value in kw.items():
    #         self._set(key, value)

    def save_data_to_file(self, data, file_path=None):
        if file_path is not None:
            self.file_path = file_path
        with open(self.file_path, 'w') as fp:
            yaml.safe_dump(data, fp, encoding='utf-8')


class OptINI:

    def __init__(self, file_path):
        self.file_path = file_path
        self.parser = ConfigParser()
        self.parser.read(self.file_path, encoding='utf-8')

    def get_value(self, section, option):
        self.parser.get(section, option)

    def set_value(self, section, option, value):
        self.parser.set(section, option, value)

    def save_data_to_file(self, file_path=None):
        if file_path is not None:
            self.file_path = file_path
        with open(self.file_path, 'w', encoding='utf-8') as fp:
            self.parser.write(fp)


class OptJson:

    def __init__(self, file_path):
        self.file_path = file_path
        self.data = demjson.decode_file(self.file_path)

    def get_data(self):
        return self.data

    def save_data_to_file(self, data, file_path=None):
        if file_path is not None:
            self.file_path = file_path
        # 此处没有使用demjson的encode_to_file方法，是因为不能使用缩进美化保存
        with open(self.file_path, 'w', encoding='utf-8') as fp:
            json.dump(fp=fp, obj=data, indent=4)


class OptMysql:

    def __init__(self, host, database, user, password, port=3306, charset='utf-8'):
        self.con = pymysql.connect(
            host=host,
            port=port,
            database=database,
            user=user,
            password=password,
            charset=charset
        )
        self.cursor = self.con.cursor()

    def execute(self, sql):
        self.cursor.execute(sql)

    def close(self):
        self.cursor.close()
        self.con.close()


class OptXML:

    """
    要用xpath定位节点，得使用lxml模块
    """

    def __init__(self, file_path):
        self.file_path = file_path
        self.dom = minidom.parse(self.file_path)
        self.root = self.dom.documentElement

    def _get_element(self, tagname):
        ele_list = self.root.getElementsByTagName(tagname)
        return ele_list

    def get_value_by_tagname(self, tagname):
        value_list = []
        ele_list = self._get_element(tagname)
        for ele in ele_list:
            value_list.append(ele.childNodes[0].data)
        return value_list

    def set_value_by_tagname(self, tagname, value):
        ele_list = self._get_element(tagname)
        for ele in ele_list:
            ele.childNodes[0].data = value

    def save_data_to_file(self, file_path=None):
        if file_path is not None:
            self.file_path = file_path
        with open(self.file_path, 'w', encoding='utf-8') as fp:
            self.root.writexml(fp)
